package com.qianfeng.zhangwei.day46.utils;

import android.os.Build;
import android.util.Log;

import org.jivesoftware.smack.AccountManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * @Package com.android.killtencent.connection
 * @作 用:
 * @创 建 人: zhangwei
 * @日 期: 15/2/9
 * @修 改 人:
 * @日 期:
 */
public class XmppConnectionHelper {
    /**
     * 服务器端口
     */
    private int SERVER_PORT = 5222;
    /**
     * 服务器ip
     */
    private String SERVER_HOST = "192.168.1.119";
    /**
     * 客服端类型
     */
    private String SERVER_NAME = "android";
    private static XmppConnectionHelper helper;
    private static XMPPConnection connection;

    private XmppConnectionHelper() { /** 私有化构造器，进行单例模式设计*/}

    public synchronized static XmppConnectionHelper getInstance() {
        if (helper == null) {
            helper = new XmppConnectionHelper();
        }
        return helper;
    }

    /**
     * 创建连接
     */
    public XMPPConnection getConnection() {
        if (connection == null) {
            openConnection();
        }
        return connection;
    }
    /**
     * 关闭连接
     */
    public void closeConnection() {
        if(connection!=null){
            //移除连接监听
            //connection.removeConnectionListener(connectionListener);
            if(connection.isConnected())
                connection.disconnect();
            connection = null;
        }
        Log.i("XmppConnection", "关闭连接");
    }

    private boolean openConnection() {
        boolean isConnection = false;
        /**
         * 参数说明 : 1.服务器端口 2.服务器Ip地址,3.客服端类型
         */
        ConnectionConfiguration configuration = new ConnectionConfiguration(SERVER_HOST, SERVER_PORT, SERVER_NAME);
        //允许debug模式
        configuration.setDebuggerEnabled(true);
        //允许断线重连
        configuration.setReconnectionAllowed(true);
        //是否启用安全验证
        configuration.setSASLAuthenticationEnabled(false);
        /**
         * 是否启用TLS安全传输协议
         * 安全传输层协议（TLS）用于在两个通信应用程序之间提供保密性和数据完整性。
         * 该协议由两层组成： TLS 记录协议（TLS Record）和 TLS 握手协议（TLS Handshake）。
         * 较低的层为 TLS 记录协议，位于某个可靠的传输协议（例如 TCP）上面，
         * 与具体的应用无关，所以，一般把TLS协议归为传输层安全协议。
         */
        configuration.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        /**
         * 设置离线状态,方便获取用户离线信息
         */
        configuration.setSendPresence(true);

        /**
         * 配置密钥凭证
         *
         * CA证书
         * 保密性 - 只有收件人才能阅读信息。
         * 认证性 - 确认信息发送者的身份。
         * 完整性 - 信息在传递过程中不会被篡改。
         * 不可抵赖性 - 发送者不能否认已发送的信息。
         *
         */
        if (Build.VERSION.SDK_INT >= 14) {
            configuration.setTruststoreType("AndroidCAStore"); //$NON-NLS-1$
            configuration.setTruststorePassword(null);
            configuration.setTruststorePath(null);
        } else {
            configuration.setTruststoreType("BKS"); //$NON-NLS-1$
            String path = System.getProperty("javax.net.ssl.trustStore"); //$NON-NLS-1$
            if (path == null)
                path = System.getProperty("java.home") + File.separator //$NON-NLS-1$
                        + "etc" + File.separator + "security" //$NON-NLS-1$ //$NON-NLS-2$
                        + File.separator + "cacerts.bks"; //$NON-NLS-1$
            configuration.setTruststorePath(path);
        }
        connection = new XMPPConnection(configuration);
        isConnection = true;
        try {
            connection.connect();
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return isConnection;
    }

    /**
     * 0 链接服务器失败 1 登陆成功 2 登陆异常
     *
     * @param name
     * @param psw
     * @return
     */
    public int login(String name, String psw) {
        int state = 0;
        if (getConnection() != null) {
            try {
                getConnection().login(name, psw);
                state = 1;
            } catch (XMPPException e) {
                e.printStackTrace();
                state = 2;
            }
        }
        return state;
    }


    /**
     * 注册
     *
     * @param account  注册帐号
     * @param password 注册密码
     * @return 1、注册成功  2、这个账号已经存在
     */
    public int registerUser(String account, String password) {
        int state = 0;
        AccountManager manager = getConnection().getAccountManager();
        try {
            manager.createAccount(account, password);
            state = 1;
        } catch (XMPPException e) {
            e.printStackTrace();
            state = 2;
        }
        return state;
    }

    /**
     * 更改用户状态
     *
     * @param code 状态码
     *             code ： 0.在线 1.Q我吧 2.忙碌 3.离开 4.隐身 5.离线
     */
    public void setPresence(int code) {
        XMPPConnection con = getConnection();
        if (con == null)
            return;
        Presence presence;
        switch (code) {
            case 0:
                presence = new Presence(Presence.Type.available);
                con.sendPacket(presence);
                Log.v("state", "设置在线");
                break;
            case 1:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.chat);
                con.sendPacket(presence);
                Log.v("state", "设置Q我吧");
                break;
            case 2:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.dnd);
                con.sendPacket(presence);
                Log.v("state", "设置忙碌");
                break;
            case 3:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.away);
                con.sendPacket(presence);
                Log.v("state", "设置离开");
                break;
            case 4:
                Roster roster = con.getRoster();
                Collection<RosterEntry> entries = roster.getEntries();
                for (RosterEntry entry : entries) {
                    presence = new Presence(Presence.Type.unavailable);
                    presence.setPacketID(Packet.ID_NOT_AVAILABLE);
                    presence.setFrom(con.getUser());
                    presence.setTo(entry.getUser());
                    con.sendPacket(presence);
                    Log.v("state", presence.toXML());
                }
                // 向同一用户的其他客户端发送隐身状态
                presence = new Presence(Presence.Type.unavailable);
                presence.setPacketID(Packet.ID_NOT_AVAILABLE);
                presence.setFrom(con.getUser());
                presence.setTo(StringUtils.parseBareAddress(con.getUser()));
                con.sendPacket(presence);
                Log.v("state", "设置隐身");
                break;
            case 5:
                presence = new Presence(Presence.Type.unavailable);
                con.sendPacket(presence);
                Log.v("state", "设置离线");
                break;
            default:
                break;
        }
    }

    /**
     * 添加一个分组
     *
     * @param groupName
     * @return
     */
    public boolean addGroup(String groupName) {
        if (getConnection() == null)
            return false;
        try {
            getConnection().getRoster().createGroup(groupName);
            Log.v("addGroup", groupName + "创建分组成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除分组
     *
     * @param groupName
     * @return
     */
    public boolean removeGroup(String groupName) {
        if (getConnection() == null)
            return false;
        try {
            getConnection().getRoster().createGroup(groupName);
            Log.v("addGroup", groupName + "创建分组成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取所有组
     *
     * @return 所有组集合
     */
    public List<RosterGroup> getGroups() {
        if (getConnection() == null)
            return null;
        List<RosterGroup> grouplist = new ArrayList<RosterGroup>();
        Collection<RosterGroup> rosterGroup = getConnection().getRoster()
                .getGroups();
        Iterator<RosterGroup> i = rosterGroup.iterator();
        while (i.hasNext()) {
            grouplist.add(i.next());
        }
        return grouplist;
    }

    /**
     * 获取某个组里面的所有好友
     *
     * @param groupName
     *            组名
     * @return
     */
    public List<RosterEntry> getEntriesByGroup(String groupName) {
        if (getConnection() == null)
            return null;
        List<RosterEntry> Entrieslist = new ArrayList<RosterEntry>();
        RosterGroup rosterGroup = getConnection().getRoster().getGroup(
                groupName);
        Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();
        Iterator<RosterEntry> i = rosterEntry.iterator();
        while (i.hasNext()) {
            Entrieslist.add(i.next());
        }
        return Entrieslist;
    }


}